#include "golink_msg_decode.h"
#include "golink_includes.h"
#include "floor_sys.h"
#include "hal_slave_floor.h"
#include "hal_tm1616.h"
#include "free_math.h"
#include "hal_tty.h"
#include "hal_key.h"

#include "FreeRTOS.h"
#include "task.h"

int do_floor_info_msg(golink_floor_info_t *info) {
	
	if(info->state) {
		//钥匙锁
		if(info->state & 0x01) {
			if(g_floor_ctrl_.lock_state_ == 0) {
				g_floor_ctrl_.lock_state_ = 1;
				//@todo !!!!
			}
		} else {
			if(g_floor_ctrl_.lock_state_ == 1) {
				g_floor_ctrl_.lock_state_ = 0;
				//@todo !!!!
			}
		}
		
		//急停
//		if(info->state & 0x02) {
//		
//		}
	}
	
	uint8_t tmp_floor;
	g_floor_ctrl_.slave_fmask_ |= info->floor_addr;
	
	if(info->pc_state && info->floor_addr != g_floor_ctrl_.cur_floor_) {
			g_floor_ctrl_.cur_floor_ = info->floor_addr;
			tmp_floor = g_floor_ctrl_.target_floor_;

			if(g_floor_ctrl_.continue_mode_) {
				if(g_floor_ctrl_.target_floor_ == 0) 
					tmp_floor = g_floor_ctrl_.lost_floor_;
			}
			
			if(tmp_floor & (1 << (g_floor_ctrl_.cur_floor_ - 1)))
				fsm_event_handle(g_floor_ctrl_.cur_fsm,SYSTEM_EVENT_FLOOR_REACH);
			else {
				if(g_test_.test_mode())
					fsm_event_handle(g_floor_ctrl_.cur_fsm,SYSTEM_EVENT_REACH);	
			}
	}
	
	if(info->key_state_click || info->key_state_double) {
		g_floor_ctrl_.req_floor_ = info->key_state_click;
		g_floor_ctrl_.remove_floor_ = info->key_state_click;
		fsm_event_handle(g_floor_ctrl_.cur_fsm,SYSTEM_EVENT_CHANGE_JOB);
	}
	
	if(info->key_long_click) {
		g_floor_ctrl_.soft_fault_ = 0;
		fsm_event_handle(g_floor_ctrl_.cur_fsm,SYSTEM_EVENT_CLEAR_STATE);
	}
}

int do_floor_master_hb(golink_heart_beat_t *hb) {

	TickType_t xLastWakeTime;
    xLastWakeTime = xTaskGetTickCount();
	
//@todo load master show led
	//g_tty_.printf("fault : %02x\r\n",g_floor_slave_.master_fault_);
	if(hb->fault != g_floor_slave_.master_fault_) {
		g_floor_slave_.master_fault_ = hb->fault;
	}
	
	if(hb->show_floor != g_floor_slave_.show_addr) {
		g_floor_slave_.show_addr = hb->show_floor;
	}
	
	if(g_floor_slave_.mode != hb->mode) {
		g_floor_slave_.mode = hb->mode;
	}
	
	if(g_floor_slave_.run_dir_ != hb->run_dir) {
		g_floor_slave_.run_dir_ = hb->run_dir;
	}
	
	if(g_floor_slave_.target_floor_ != hb->target_floor) {
		g_floor_slave_.target_floor_ = hb->target_floor;
	}
	
//@todo load end!!
	
//@todo send slave state
	uint32_t delay_tick = 0;
	uint8_t update_flag = 0;
	if(g_slave_ctrl_.get_pc_state()) {
		//直接发送反馈
		delay_tick = 1;
		update_flag = 1;
	}
	
	if(update_flag == 0 && (g_slave_state_.update_flag || hb->floor_alive == 0xFF)) {
		//@todo 计算 delay tick
		
		uint8_t tmp_floor = 1 << g_slave_state_.slave_addr;
		if(tmp_floor) {
			tmp_floor = tmp_floor - 1;
			uint8_t count = count_ones_uint8(hb->floor_alive & tmp_floor) + 1;
			delay_tick = hb->time_offset * count;
		}
		
		update_flag = 1;
	}

	//g_tty_.printf("update_flag : %d delay_tick : %d\r\n",update_flag,delay_tick);
	if(update_flag) {
		if(delay_tick)
			vTaskDelayUntil(&xLastWakeTime,pdMS_TO_TICKS(delay_tick));
		
		golink_floor_info_t info;
		info.state = 0;
		
		if(g_slave_ctrl_.get_lock_state())
			info.state = 1;
		
		//@todo 急停 door！！！
		//if(g_slave_ctrl_.)
		//  door!!!
	
		info.key_state_click = g_slave_state_.click_state;
		info.key_state_double = g_slave_state_.double_click_state;
		info.key_long_click = g_slave_state_.long_key_state;
		info.slave_fault = g_slave_state_.slave_fault_;
		info.floor_addr = g_slave_state_.slave_addr;
		info.pc_state = g_slave_ctrl_.get_pc_state();
		
		g_tty_.printf("key_state_click : %02x  double : %02x \r\n",g_slave_state_.click_state,g_slave_state_.double_click_state);

		golink_send_floor_info(&info);
		g_slave_state_.update_flag = 0;
		g_slave_state_.click_state = 0;
		g_slave_state_.double_click_state = 0;
		g_slave_state_.long_key_state = 0;
	}
}



